#include "stdafx.h"
#include "Server.h"
#include "ThreadManager.h"
#include "LFAcceptor.h"

using namespace Network;

const int MAX_THREADS = 5;
void *worker_thread (void *arg);

int _tmain(int argc, _TCHAR* argv[])
{
	//Starts the server
	WSADATA wsaData;
	fprintf(stdout, "Welcome to the server\n");
	
	//Start Winsock
	int wsResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (wsResult != 0) {
		fprintf(stdout, "WSAStartup failed with error: %d\n", wsResult);	
		WSACleanup();
		return -1;
	}

	//Create listeners on different ports
	INET_Addr alarmAddress(LISTENING_IF, ALARM_PORT);
	INET_Addr logAddress(LISTENING_IF, LOG_PORT);
	INET_Addr patientAddress(LISTENING_IF, PATIENT_PORT);

	//Create the threadpool
	LFThreadPool threadpool = LFThreadPool(SelectReactor::instance(), 10);
	
	//Create EventHandlers
	LFAcceptor<AlarmEventHandler> alarmEvent(alarmAddress, SelectReactor::instance(), &threadpool);
	LFAcceptor<AlarmEventHandler> logEvent(logAddress, SelectReactor::instance(), &threadpool);
	LFAcceptor<AlarmEventHandler> patientEvent(patientAddress, SelectReactor::instance(), &threadpool);
	
	//AlarmEventHandler* alarmEvent = new AlarmEventHandler(alarmAddress, threadpool);
	//LoggingEventHandler* logEvent = new LoggingEventHandler(logAddress, threadpool);
	//PatientEventHandler* patientEvent = new PatientEventHandler(patientAddress, threadpool);

	threadpool.Start();
	for( unsigned int i = 0; i < MAX_THREADS; i++ ) {
		ThreadManager::instance()->spawn(worker_thread, &threadpool);
	}

	//while(true){
	//	SelectReactor::instance()->handle_events();
	//}

	//printf("Thread pool joining\n");
	//threadpool->Join(INFINITE);
	
	while(true){
		//do nothing
	}
	//Clean up winsock
	WSACleanup();
	return 0;
}

void *worker_thread (void *arg) {
		if( !arg )
		{
			return 0; 
		}

		LFThreadPool* object = static_cast<LFThreadPool*> (arg);
		printf("Spawned new thread with ID = 0x%x\n", GetCurrentThreadId());
	
		object->Join( THREAD_LOCK_TIMEOUT_MS );

		return 0;
}